/*
 * Copyright (c) 2023-2024 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.mybatis.configuration;

import jakarta.servlet.DispatcherType;
import lombok.extern.slf4j.Slf4j;
import org.elsfs.cloud.common.mybatis.properties.MybatisPlusProperties;
import org.elsfs.cloud.tenant.api.handler.DefaultTenantReader;
import org.elsfs.cloud.tenant.api.handler.TenantContextFilter;
import org.elsfs.cloud.tenant.api.handler.TenantReader;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 多租户上下文配置
 *
 * @author zeng
 */
@Slf4j
@AutoConfiguration
@EnableConfigurationProperties({MybatisPlusProperties.class, SecurityProperties.class})
@ConditionalOnProperty(
    value = {"elsfs.mybatis.tenant.enabled"},
    matchIfMissing = true)
public class TenantContextConfiguration {

  /**
   * 配置多租户读取器的注册信息。 该配置仅在特定属性（"elsfs.mybatis.tenant.enabled"）存在或缺失时应用。
   *
   * @param securityProperties 安全属性，用于设置过滤器的执行顺序
   * @return FilterRegistrationBean 租户上下文过滤器的注册信息
   */
  @Bean
  public FilterRegistrationBean<TenantContextFilter> filterRegistrationBean(
      SecurityProperties securityProperties, TenantReader tenantReader) {
    LOGGER.info("正在配置多租户上下文过滤器！！！！！"); // 日志记录，表示开始配置租户上下文过滤器
    TenantContextFilter tenantContextFilter = new TenantContextFilter();
    tenantContextFilter.setTenantReader(tenantReader);
    FilterRegistrationBean<TenantContextFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(tenantContextFilter); // 设置过滤器实例
    registration.addUrlPatterns("/*"); // 设置过滤器适用的所有URL模式
    registration.setName("tenantContextFilter"); // 设置过滤器的注册名称
    registration.setDispatcherTypes(DispatcherType.REQUEST); // 设置过滤器适用的Dispatcher类型
    registration.setOrder(
        securityProperties.getFilter().getOrder() - 1); // 设置过滤器的执行顺序，确保其在Spring Security之前执行
    return registration; // 返回配置的过滤器注册信息
  }

  @Configuration
  @ConditionalOnMissingBean(TenantReader.class)
  static class DefaultTenantReaderAutoConfiguration {
    @Bean
    public TenantReader tenantReaderObjectProvider() {
      return new DefaultTenantReader();
    }
  }
}
